package net.daum.codegen;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import net.daum.codegen.dao.SchemaDao;
import net.daum.codegen.domain.Part;
import net.daum.codegen.domain.Table;

import org.apache.commons.io.FileUtils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class GenProject {
	
	private static final String OBJECT_PREFIX = "Sample";
	private static final String SCHEMA = "auto";
	private static final String PACKAGE = "net.daum.auto";
	
	private SchemaDao schemaDao;
	private List<Table> tableList;
	
	public GenProject()	throws Exception {
		this.schemaDao = DatabaseUtil.getDao();
		Table table = new Table();
		table.setSchema(SCHEMA);		
	}
	
	public void run() throws Exception {
		FileUtils.deleteQuietly(new File("result"));
		
		Table table = new Table();
		table.setSchema(SCHEMA);
		
		this.tableList = schemaDao.selectTableList(table);
		for (Table currentTable : tableList) {
			currentTable.setSchema(table.getSchema());
			currentTable.setColumnList(schemaDao.selectColumnList(currentTable));
		}		
		
		List<Part> partList = Lists.newArrayList(CodeGenUtil.partMap.values());
		
		for (Part part : partList) {
			createFile(part);			
		}		
	}

	private String getPackageDirectory() {
		return getPackageDirectory(PACKAGE);
	}
	
	private String getPackageDirectory(String packageName) {
		return packageName.replaceAll("\\.",  "/");
	}

	private void createFile(Part part) throws Exception, IOException {
		
		String directoryName = "result/src/" + getPackageDirectory() + "/" + getPackageDirectory(part.getSubPackageName());
		new File(directoryName).mkdirs();
		
		if (part.getName().equals("Domain")) {
			for (Table table : this.tableList) {
				table.setPackageName(PACKAGE + "." + part.getSubPackageName());
				File file = new File(directoryName, CodeGenUtil.getJavaClassName(table.getName()) + part.getExt());
				Map<String, Object> domainMap = new LinkedHashMap<String, Object>();
				domainMap.put("table", table);
				domainMap.put("genProject", GenProject.class);
				FileUtils.writeStringToFile(file, VelocityProcess.getResult("velocity/" + part.getName() + ".vm", domainMap));
				System.out.println(file.getCanonicalPath());
			}
			return;
		}
		
		StringBuffer content = new StringBuffer();
		for (Table table : this.tableList) {
			Map<String, Object> domainMap = new LinkedHashMap<String, Object>();
			domainMap.put("table", table);
			domainMap.put("genProject", GenProject.class);
			content.append(VelocityProcess.getResult("velocity/" + part.getName() + ".vm", domainMap));
		}
		
		Map<String, Object> map = Maps.newHashMap();
		map.put("content", content.toString());
		map.put("packageName", PACKAGE + "." + part.getSubPackageName());
		map.put("name", OBJECT_PREFIX + part.getName());		
		map.put("parent", OBJECT_PREFIX + part.getParent());		
		map.put("tableList", this.tableList);
		map.put("genProject", GenProject.class);		
		
		File file = new File(directoryName, OBJECT_PREFIX + part.getName() + part.getExt());			
		
		FileUtils.writeStringToFile(file, VelocityProcess.getResult("velocity/Entire" + part.getName() + ".vm", map));
		System.out.println(file.getCanonicalPath());
	}	
	
	public static String getPackageName() {
		return PACKAGE;
	}

	public static void main(String[] args) throws Exception {
		new GenProject().run();
	}
}
